<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>leaflet显示</title>
  <script include="jquery,moment" src="./static/libs/include-lib-local.js"></script>
  <script include="language,elasticsearch,geojson,geohash,mapv" src="./static/libs/include-mapboxgl-local.js"></script>
  <style>
    body {
      margin: 0;
      padding: 0;
    }

    #map {
      position: absolute;
      top: 0;
      bottom: 0;
      width: 100%;
    }
  </style>
</head>

<body>
  <div id="map"></div>
  <script>
    mapboxgl.accessToken =
      'pk.eyJ1IjoicGFybmRlZWRsaXQiLCJhIjoiY2o1MjBtYTRuMDhpaTMzbXhpdjd3YzhjdCJ9.sCoubaHF9-nhGTA-sgz0sA';
    var map = new mapboxgl.Map({
      container: 'map',
      style: 'mapbox://styles/mapbox/dark-v9',
      /* style: {
        "version": 8,
        "sources": {
          "mapbox-tiles": {
            "type": "raster",
            'tiles': [
              "https://api.tiles.mapbox.com/v4/mapbox.dark/{z}/{x}/{y}.png?access_token=sk.eyJ1IjoiY2hlbmdkYWRhIiwiYSI6ImNqZDFjaGo0ZjFzcnoyeG54enoxdnNuZHUifQ.hTWXXBUQ0wdGeuDF3GWeUw"
            ],
            'tileSize': 256
          }
        },
        "layers": [{
          "id": "dark-tiles",
          "type": "raster",
          "source": "mapbox-tiles",
          "minzoom": 0,
          "maxzoom": 22
        }]
      }, */
      zoom: 7,
      pitch: 45,
      center: [108.95, 34.25]
    });
    var startTime, currentTime;
    startTime = currentTime = Date.parse(new Date("2018-06-25 00:45:19")); //1516723200000; 毫秒
    var client = new elasticsearch.Client({
      host: 'http://192.168.96.101:9200'
    });


    map.addControl(new MapboxLanguage(), 'top-right'); //中文支持

    var mapvLayer;
    var tempCenter, tempData = {
      "type": "FeatureCollection",
      "features": []
    };

    var minCount = Number.MAX_VALUE;
    var maxCount = 0;
    var avaCount = 0,
      allCount = 0;


    innerTest();

    function innerTest() {
      var bound = wrapLatLngBounds(map.getBounds());
      client.search({
        index: 'spbsfy', //数据库名称
        body: {
          size: 0, //此处返回的是hits的数组大小
          query: {
            bool: {
              filter: {
                range: {
                  'dataTime': {
                    from: startTime,
                    to: startTime + 600000000000
                  }
                }
              }
            }
          },
          aggregations: {
            'mapExtent': {
              filter: {
                geo_bounding_box: {
                  'geometry': {
                    top_left: {
                      lat: bound.getNorthWest().lat,
                      lon: bound.getNorthWest().lng
                    },
                    bottom_right: {
                      lat: bound.getSouthEast().lat,
                      lon: bound.getSouthEast().lng
                    }
                  }
                }
              },
              aggregations: {
                'geohash': {
                  geohash_grid: {
                    field: "geometry",
                    precision: 6
                  }
                }
              }
            }
          }
        }
      }, getInnerData);
    }

    function getInnerData(error, response) {
      response.aggregations.mapExtent.geohash.buckets.forEach(function (bucket) {
        var coordinates = decodeGeoHash(bucket.key);
        var countNumber = bucket.doc_count;
        var feature = {
          "type": "Feature",
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              [
                [coordinates.longitude[0], coordinates.latitude[1]],
                [coordinates.longitude[1], coordinates.latitude[1]],
                [coordinates.longitude[1], coordinates.latitude[0]],
                [coordinates.longitude[0], coordinates.latitude[0]],
                [coordinates.longitude[0], coordinates.latitude[1]]
              ]
            ]
          },
          "properties": {
            "doc_count": bucket.doc_count
          }
        };
        if (countNumber > maxCount) maxCount = countNumber;
        if (countNumber < minCount) minCount = countNumber;

        tempData.features.push(feature);
      });

      allCount = response.aggregations.mapExtent.doc_count;
      avaCount = allCount / response.aggregations.mapExtent.geohash.buckets.length;

      console.log("maxCount:" + maxCount + " minCount:" + minCount);
      updateView();
    }

    function updateView() {
      var minHeight = 200, maxHeight = 15000;
      var levelCount = 15; //分类的最大级别
      var heightDegrees = []; //分类级别的阈值范围
      var levelClip = 5; // 15 = 5 + 10 5表示0-5是低级别的  6-15是高级别  分开的目的是往往数据要么集中再低级别要么集中再高级别的正太分布而不是均匀分布的
      var highDegreeLength = maxCount - avaCount;//高级别跨度
      var lowDegreeLength = avaCount - minCount;//低级别跨度
      var highDegree = highDegreeLength / (levelCount - levelClip);//高级别跨度每层范围
      var lowDegree = lowDegreeLength / levelClip;//低级别跨度每层范围
      var startDegree = minCount;

      for (var level = 0; level < levelCount; level++) {
        if (level < levelClip) {
          startDegree = startDegree + lowDegree;
        } else {
          startDegree = startDegree + highDegree;
        }
        heightDegrees.push(startDegree);
      }

      map.addSource("cubeSource", {
        "type": "geojson",
        "data": tempData
      });

      map.addLayer({
        "id": "cudeLayer", //id不同重复，否则只绘制一次
        "type": "fill-extrusion",
        "source": "cubeSource", //必须和上面的geojsonCollections一致
        "paint": {
          "fill-extrusion-base": 10,
          "fill-extrusion-height": {
            "property": 'doc_count',
            "stops": [
              [{
                zoom: 0,
                value: minCount
              }, minHeight],
              [{
                zoom: 0,
                value: maxCount
              }, maxHeight]
            ]
          },
          "fill-extrusion-color": {
            "property": 'doc_count',
            "stops": [
              [1, "rgb(0,41,81)"],
              [heightDegrees[0], "rgb(1,19,157)"],
              [heightDegrees[1], "rgb(4,37,212)"],
              [heightDegrees[2], "rgb(6,74,243)"],
              [heightDegrees[3], "rgb(13,149,233)"],
              [heightDegrees[4], "rgb(25,207,210)"],
              [heightDegrees[5], "rgb(130,253,206)"],
              [heightDegrees[6], "rgb(104,222,134)"],
              [heightDegrees[7], "rgb(164,235,79)"],
              [heightDegrees[8], "rgb(255,255,128)"],
              [heightDegrees[9], "rgb(255,214,0)"],
              [heightDegrees[10], "rgb(254,173,91)"],
              [heightDegrees[11], "rgb(250,124,1)"],
              [heightDegrees[12], "rgb(254,0,0)"],
              [heightDegrees[13], "rgb(129,0,65)"],
              [heightDegrees[14], "rgb(65,0,64)"]
            ]
          },
          "fill-extrusion-opacity": {
            "base": 1,
            "stops": [
              [10, 0.8],
              [12.5, 0.6],
              [14, 0.4]
            ]
          }
        }
      });
    }

    function wrapLatLngBounds(bound) {
      var left = bound.getWest() < -180 ? -179.99 : bound.getWest();
      var bottom = bound.getSouth() < -90 ? -89.99 : bound.getSouth();
      var right = bound.getEast() > 180 ? 179.99 : bound.getEast();
      var top = bound.getNorth() > 90 ? 89.99 : bound.getNorth();
      return new mapboxgl.LngLatBounds(
        new mapboxgl.LngLat(left, bottom),
        new mapboxgl.LngLat(right, top));
    }
  </script>
</body>

</html>